﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SerialPortHelperLib
{
  public  class Sensor_i2c
    {
        private SerialPort sPortTemp;

        private uint add;
        private uint reg;
        private uint val;
        

        public delegate void SendEventSensor_i2cNewClick(string msg);

        public event SendEventSensor_i2cNewClick SendSensor_i2cClick;

        private bool checkBox1;
        private bool checkBox2;
        private bool checkBox3;
        private bool debugEN = true;

        /// <summary>
        /// 初始化变量
        /// </summary>
        /// <param name="_add"></param>
        /// <param name="_reg"></param>
        /// <param name="_val"></param>
        /// <param name="_sPortTemp"></param>
        public Sensor_i2c(uint _add, uint _reg, uint _val,bool _checkBox1,bool _checkBox2,bool _checkBox3, SerialPort _sPortTemp) {
            add = _add;
            reg = _reg;
            val = _val;
            checkBox1 = _checkBox1;
            checkBox2 = _checkBox2;
            checkBox3 = _checkBox3;
            sPortTemp = _sPortTemp;

        }

        public Sensor_i2c(uint _add, bool _checkBox1, bool _checkBox2, bool _checkBox3, SerialPort _sPortTemp)
        {
            add = _add;
            checkBox1 = _checkBox1;
            checkBox2 = _checkBox2;
            checkBox3 = _checkBox3;
            sPortTemp = _sPortTemp;
        }   
        private void AE_Disable() {
            //isp_write(0x20000032, 0x0);
        }

        public void AE_Enable()
        {
            //isp_write(0x20000032, 0x1);
        }

        //private void I2cToWrite8050004e() {
        //    uint recdata = 0;
        //    ReadRegDataARM(0x31, 0x8050004e, ref recdata);
        //    recdata &= 0x10;//bit3=1
        //    SendRegDataARM(0x21, 0x8050004e, recdata);
        //}
        private void I2C_Switch_Master() {
           
            var recdata = ReadRegister(0x31, 0x8050004e).ToString("X2");
            ulong value = Convert.ToUInt32(recdata, 16) | 0x10;
            WriteRegister(0x21, 0x8050004e, value);
        }
        public  long ReadRegister(byte a, ulong addr)
        {
            uint DATA = 0;
            long test_value1 = (long)0x82000000;
            uint test_value2 = (uint)0x00000000;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);
            SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0);
            ReadRegDataARM(a, (uint)addr, ref DATA);
            return DATA;
        }
        public  void WriteRegister(byte a, ulong addr, ulong value)
        {
            long test_value1 = (long)0x82000000;
            uint test_value2 = (uint)0x00000000;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);
            SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0);
            int byte_sel = (int)(addr) & 0x3;
            byte_sel = byte_sel * 8;
            value = value & 0xff;
            value = value << byte_sel;
            SendRegDataARM(a, (uint)addr, (uint)value);
        }

        private void I2C_Switch_Slaver()
        {
            //uint recdata = 0;
            //ReadRegDataARM(0x31, 0x8050004e, ref recdata);
           
            //SendRegDataARM(0x21, 0x8050004e, recdata & (~0x10U));

            var recdata = ReadRegister(0x31, 0x8050004e).ToString("X2");
            ulong value = Convert.ToUInt32(recdata, 16) & (~0x10U);
            WriteRegister(0x21, 0x8050004e, value);
        }


        private void I2C_RDY()
        {
            var dt0 = DateTime.Now;
            while ((read(0x80250000 + 0x08) & 0x01) != 0x0)
            {
                if (SerialSend.DateDiffMs(dt0) > 3000)
                {
                    SendSensor_i2cClick?.Invoke("错误：超时");
                    break;
                }
            };
        }

        private void i2c_writereg(uint addr, uint val)
        {// I2C 硬件寄存器写
            isp_write(0x80250000 + addr, val);
        }

        private uint i2c_readreg(uint addr)
        {
            uint I2C_addr_base = 0x80250000;
            return read(I2C_addr_base + addr);
        }

        private uint read(uint reg_address)
        {
            uint val = 0;
            ReadRegDataARM(0x31, reg_address, ref val);
            return val;
        }
        private void isp_write(uint reg_address, uint reg_data)
        {
            int byte_sel = (int)(reg_address) & 0x3;
            byte_sel = byte_sel * 8;

            reg_data = reg_data & 0xff;
            reg_data = reg_data << byte_sel;
            SendRegDataARM(0x21, reg_address, reg_data);
        }


        public byte SendRegData(byte a, uint ADDR, uint DATA) {
            byte[] sendbuf = new byte[9];
            byte[] buf = new byte[9]; //声明一个临时数组存储当前来的串口数据     
            byte value = 0x00;
            //TXD0 ADDRESS
            sendbuf[0] = a;//com choose write or byte write
            //TXD0 ADDRESS
            sendbuf[1] = (byte)((ADDR >> 0) & 0xff);
            sendbuf[2] = (byte)((ADDR >> 8) & 0xff);
            sendbuf[3] = (byte)((ADDR >> 16) & 0xff);
            sendbuf[4] = (byte)((ADDR >> 24) & 0xff);
            //大端模式
            sendbuf[5] = (byte)((DATA >> 24) & 0xff);
            sendbuf[6] = (byte)((DATA >> 16) & 0xff);
            sendbuf[7] = (byte)((DATA >> 8) & 0xff);
            sendbuf[8] = (byte)((DATA >> 0) & 0xff);

            if (sPortTemp.IsOpen == true)
            {
                CommRecvBufClear();
                sPortTemp.Write(sendbuf, 0, 9);
                if (checkBox1 && debugEN)
                {
                    SendSensor_i2cClick?.Invoke("Send Write Cmd:");
                }
                data_disp(sendbuf, 9);
                for (int i = 0; i < 100; i++)
                {
                    if (sPortTemp.BytesToRead > 0)
                    {
                        int n = sPortTemp.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致 
                        if (n >= 8)
                            n = 8;
                        sPortTemp.Read(buf, 0, n);//读取缓冲数据
                        if (checkBox1&&debugEN)
                        {
                            SendSensor_i2cClick?.Invoke("Recv Data: ");
                        }
                        data_disp(buf, n);
                        value = buf[0];

                        break;
                    }
                    else
                        Thread.Sleep(10);
                }

            }
            else {
                if (null != SendSensor_i2cClick)
                {
                    SendSensor_i2cClick("串口关闭！");
                }
            }
            if (value !=a)
            {
                if (null != SendSensor_i2cClick)
                {
                    SendSensor_i2cClick($"fail in send: {ADDR.ToString("X2")}\r\n");
                }
            }
            return value;
        }

        public byte ReadRegData(byte a, uint ADDR, ref uint DATA) {
            byte[] readbuf = new byte[15];
            byte[] buf = new byte[10];
            byte value = 0x00;
            int recv_cnt = 0x00;
            uint byte_sel = ADDR & 0x3;
            //TXD0 ADDRESS
            readbuf[0] = a;
            //TXD0 ADDRESS
            readbuf[1] = (byte)((ADDR >> 0) & 0xff);
            readbuf[2] = (byte)((ADDR >> 8) & 0xff);
            readbuf[3] = (byte)((ADDR >> 16) & 0xff);
            readbuf[4] = (byte)((ADDR >> 24) & 0xff);
            if (sPortTemp.IsOpen == true)
            {
                CommRecvBufClear();
                //串口写
                sPortTemp.Write(readbuf, 0, 5);
                if (checkBox1 && debugEN)
                {
                    SendSensor_i2cClick?.Invoke("Recv Data: ");
                }

                data_disp(readbuf, 5);
                DATA = 0;

                int i;
                for (i = 0; i < 100; i++)
                {

                    if (sPortTemp.BytesToRead > 0)
                    {
                        int n = sPortTemp.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致     
                        //声明一个临时数组存储当前来的串口数据   

                        if (n >= 8)
                            n = 8;
                        sPortTemp.Read(buf, 0, n);//读取缓冲数据

                        if ((recv_cnt + n) >= 12)
                        {
                            n = 12 - recv_cnt;
                        }

                        for (int j = 0; j < n; j++)
                        {
                            readbuf[recv_cnt + j] = buf[j];
                        }
                        recv_cnt += n;
                        if (recv_cnt >= 5)
                        {
                            if (checkBox1 && debugEN)
                            {
                                SendSensor_i2cClick?.Invoke("Recv Read Data:");

                            }
                            data_disp(readbuf, recv_cnt);
                            value = readbuf[0];

                            if (readbuf[0] == 0x11)
                                DATA = (uint)((readbuf[1] << 24) + (readbuf[2] << 16) + (readbuf[3] << 8) + (readbuf[4] << 0));
                            else
                            {
                                switch (byte_sel)
                                {
                                    case 0:
                                        DATA = readbuf[4];
                                        break;
                                    case 1:
                                        DATA = readbuf[3];
                                        break;

                                    case 2:
                                        DATA = readbuf[2];
                                        break;
                                    case 3:
                                        DATA = readbuf[1];
                                        break;
                                    default:
                                        DATA = 0x0;
                                        break;
                                }

                            }
                            break;
                        }

                    }
                    else
                        Thread.Sleep(10);

                }

            }
            else {
                if (null != SendSensor_i2cClick)
                {
                    SendSensor_i2cClick("串口关闭！");
                }
            }


            return value;
        }


        public byte ReadRegDataARM(byte a, uint ADDR, ref uint DATA)
        {
            byte[] readbuf = new byte[15];
            byte[] buf = new byte[10];
            byte value = 0x00;
            int recv_cnt = 0x00;
            uint byte_sel = ADDR & 0x3;
            //byte_sel = (3 - byte_sel) * 8;

            //TXD0 ADDRESS
            readbuf[0] = a;
            //TXD0 ADDRESS
            readbuf[1] = (byte)((ADDR >> 0) & 0xff);
            readbuf[2] = (byte)((ADDR >> 8) & 0xff);
            readbuf[3] = (byte)((ADDR >> 16) & 0xff);
            readbuf[4] = (byte)((ADDR >> 24) & 0xff);

            //DiscardInBuffer();
            sPortTemp.Write(readbuf, 0, 5);
            //if (null != SendSerialSendClick && isDebug)
            //{
            //    SendSerialSendClick($" Send Read Cmd: {bufMsg(readbuf, 5)}");
            //}
            //SengMsg($" Send Read Cmd: {bufMsg(readbuf, 5)}");
            int i;
            for (i = 0; i < 100; i++)
            {
                if (sPortTemp.BytesToRead > 0)
                {
                    int n = sPortTemp.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致     
                                              //声明一个临时数组存储当前来的串口数据   

                    if (n >= 8)
                        n = 8;
                    sPortTemp.Read(buf, 0, n);//读取缓冲数据

                    if ((recv_cnt + n) >= 12)
                    {
                        n = 12 - recv_cnt;
                    }

                    for (int j = 0; j < n; j++)
                    {
                        readbuf[recv_cnt + j] = buf[j];
                    }
                    recv_cnt += n;
                    if (recv_cnt >= 5)
                    {
                        //if (null != SendSerialSendClick && isDebug)
                        //{
                        //    SendSerialSendClick($" Recv Read Data: {bufMsg(readbuf, recv_cnt)}");
                        //}
                        //SengMsg($" Recv Read Data: {bufMsg(readbuf, recv_cnt)}");
                        value = readbuf[0];

                        if (readbuf[0] == 0x11)
                            DATA = (uint)((readbuf[1] << 0) + (readbuf[2] << 8) + (readbuf[3] << 16) + (readbuf[4] << 24));
                        else
                        {
                            switch (byte_sel)
                            {
                                case 0:
                                    DATA = readbuf[1];
                                    break;
                                case 1:
                                    DATA = readbuf[2];
                                    break;

                                case 2:
                                    DATA = readbuf[3];
                                    break;
                                case 3:
                                    DATA = readbuf[4];
                                    break;
                                default:
                                    DATA = 0x0;
                                    break;
                            }

                        }
                        break;
                    }

                }
                else
                    Thread.Sleep(10);
            }


            if (value != a)
            {
                if (null != SendSensor_i2cClick)
                {
                    SendSensor_i2cClick($"fail in send: {ADDR.ToString("X2")}\r\n");
                }
                //SengMsg($"fail in send: {ADDR.ToString("X2")}\r\n");
            }
            else
            {
                if (null != SendSensor_i2cClick && a != 0x1)
                {
                    SendSensor_i2cClick($"R:0x{ADDR.ToString("X8")} 0x{DATA.ToString("X2")}");
                }
            }
            return value;
        }
        public byte SendRegDataARM(byte a, uint ADDR, uint DATA)
        {

            byte[] sendbuf = new byte[9];
            byte[] buf = new byte[9]; //声明一个临时数组存储当前来的串口数据     
            byte value = 0x00;
            int i;
            //TXD0 ADDRESS
            sendbuf[0] = a;//com choose write or byte write
            //TXD0 ADDRESS
            sendbuf[1] = (byte)((ADDR >> 0) & 0xff);
            sendbuf[2] = (byte)((ADDR >> 8) & 0xff);
            sendbuf[3] = (byte)((ADDR >> 16) & 0xff);
            sendbuf[4] = (byte)((ADDR >> 24) & 0xff);
            //小端模式
            sendbuf[5] = (byte)((DATA >> 0) & 0xff);
            sendbuf[6] = (byte)((DATA >> 8) & 0xff);
            sendbuf[7] = (byte)((DATA >> 16) & 0xff);
            sendbuf[8] = (byte)((DATA >> 24) & 0xff);

            sPortTemp.Write(sendbuf, 0, 9);
            //if (null != SendSerialSendClick && isDebug)
            //{
            //    SendSerialSendClick($" Send Read Cmd: {bufMsg(sendbuf, 9)}");
            //}
            //SengMsg($" Send Read Cmd: {bufMsg(sendbuf, 9)}");

            for (i = 0; i < 100; i++)
            {
                if (sPortTemp.BytesToRead > 0)
                {
                    int n = sPortTemp.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致 
                    if (n >= 8)
                        n = 8;
                    sPortTemp.Read(buf, 0, n);//读取缓冲数据
                    //if (null != SendSerialSendClick && isDebug)
                    //{
                    //    SendSerialSendClick($" Recv Data: {bufMsg(buf, n)}");
                    //}
                    //SengMsg($" Recv Data: {bufMsg(buf, n)}");
                    value = buf[0];

                    break;
                }
                else
                    Thread.Sleep(10);
            }

            if (value != a)
            {
                if (null != SendSensor_i2cClick)
                {
                    SendSensor_i2cClick($"fail in send: {ADDR.ToString("X2")}\r\n");
                }
                //SengMsg($"fail in send: {ADDR.ToString("X2")}\r\n");
            }
            else
            {
                if (null != SendSensor_i2cClick && a != 0x1)
                {
                    int byte_sel = (int)(ADDR) & 0x3;
                    byte_sel = byte_sel * 8;
                    var reg_data = DATA >> byte_sel;
                    reg_data = reg_data & 0xff;
                    SendSensor_i2cClick($"W:0x{ADDR.ToString("X8")} 0x{reg_data.ToString("X2")}");

                }
            }
            return value;
        }



        private void CommRecvBufClear() {

            byte[] buf = new byte[9]; //声明一个临时数组存储当前来的串口数据  
            for (int i = 0; i < 100; i++)
            {
                if (sPortTemp.BytesToRead > 0)
                {
                    int n = sPortTemp.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致  
                    if (n >= 8)
                        n = 8;
                    sPortTemp.Read(buf, 0, n);//读取缓冲数据
                }
            }
        }

        private void data_disp(byte[] buf, int len) {
            StringBuilder builder = new StringBuilder();
            if (checkBox1)
            {
                for (int i = 0; i < len; i++)
                {
                    builder.Append(buf[i].ToString("X2") + " ");
                }
                builder.Append("\r\n");
            }
            if (!string.IsNullOrEmpty(builder.ToString())&&null != SendSensor_i2cClick && debugEN)
            {
                SendSensor_i2cClick(builder.ToString());
            }
        }

        private void switch_pin_to_sensor() {
           
            uint reg_addr = 0x8050004d;
            uint senddata = 0;
            uint recdata = 0;
            int byte_sel;
            ReadRegData(0x31, reg_addr, ref recdata);
            recdata = (uint)recdata & (~0x00000002U);//bit1写0
            byte_sel = (int)(reg_addr) & 0x3;
            byte_sel = byte_sel * 8;
            senddata = recdata & 0xff;
            senddata = senddata << byte_sel;
            SendRegDataARM(0x21, reg_addr, senddata);
        }


        private void hw_i2c_write(uint addr, uint val) {

            I2C_RDY();
            i2c_writereg(0x05, addr);
            i2c_writereg(0x06, val);
            i2c_writereg(0x04, 0x37);

            //I2C_WaitReady();
        }

        private void hw_i2c_write16(uint addr, uint val)
        {
            I2C_RDY();

            i2c_writereg(0x05, (addr >> 8) & 0xff);
            i2c_writereg(0x06, addr & 0xff);
            i2c_writereg(0x04, 0x17);

            //I2C_WaitReady();

            i2c_writereg(0x06, val);
            i2c_writereg(0x04, 0x24);

            //I2C_WaitReady();

        }
        private void hw_i2c_16write16(uint addr, uint val)
        {
            i2c_writereg(0x05, (addr >> 8) & 0xff);
            i2c_writereg(0x06, addr & 0xff);
            i2c_writereg(0x04, 0x17);
            Thread.Sleep(100);

            //I2C_WaitReady();
            i2c_writereg(0x05, (val >> 8) & 0xff);
            i2c_writereg(0x06, val & 0xff);
            i2c_writereg(0x04, 0x26);
            Thread.Sleep(100);

            //I2C_WaitReady();

        }
        public void Write(uint addr, uint valr)
        {
            if (checkBox1)
            {
                // i2c_mode = 0; // 8addr 8data
                hw_i2c_write(addr, valr);
            }
            else if (checkBox2)
            {
                // i2c_mode = 1;  // 16addr 8data
                hw_i2c_write16(addr, valr);
            }
            else if (checkBox3)
            {
                // i2c_mode = 2;  // 16addr 16data
                hw_i2c_16write16(addr, valr);
            }
        }        
        public string HwRead(uint addr)
        {
            uint val = 0xfffffff; ;// = Convert.ToUInt32(sensor_val.Text, 16);
            //停止AE
            debugEN = false;
            AE_Disable();
            //I2cToWrite8050004e();
            //Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            // switch pin
            switch_pin_to_sensor();
            //发送 ID
            i2c_writereg(0x03, addr);
            //导出的文本字符串

            if (checkBox1)
            {
                // i2c_mode = 0; // 8addr 8data
                val = hw_i2c_read(addr);
            }
            else if (checkBox2)
            {
                // i2c_mode = 1;  // 16addr 8data
                val = hw_i2c_read16(addr);
            }
            else if (checkBox3)
            {
                // i2c_mode = 2;  // 16addr 16data
                val = hw_i2c_16read16(addr);
            }
            SendSensor_i2cClick?.Invoke("R:0x" + reg.ToString("X2") + " 0x" + val.ToString("X2"));

            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;

            return Convert.ToString(val, 16).ToUpper();
        }
        public void WriteBefore()
        {
            debugEN = false;
            AE_Disable();
            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            //switch pin
            switch_pin_to_sensor();
            //发送 ID
            i2c_writereg(0x03, add);
        }
        public void Write()
        {
            if (checkBox1)
            {
                // i2c_mode = 0; // 8addr 8data
                hw_i2c_write(reg, val);
            }
            else if (checkBox2)
            {
                // i2c_mode = 1;  // 16addr 8data
                hw_i2c_write16(reg, val);
            }
            else if (checkBox3)
            {
                // i2c_mode = 2;  // 16addr 16data
                hw_i2c_16write16(reg, val);
            }
            //SendSensor_i2cClick?.Invoke("W:0x" + reg.ToString("X2") + " 0x" + val.ToString("X2"));
        }
        public void WriteAfter()
        {
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;

        }
        public void HwWrite() {

            //停止AE
            debugEN = false;
            AE_Disable();
            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            //switch pin
            switch_pin_to_sensor();
            //发送 ID
            i2c_writereg(0x03, add);

            if (checkBox1)
            {
                // i2c_mode = 0; // 8addr 8data
                hw_i2c_write(reg, val);
            }
            else if (checkBox2)
            {
                // i2c_mode = 1;  // 16addr 8data
                hw_i2c_write16(reg, val);
            }
            else if (checkBox3)
            {
                // i2c_mode = 2;  // 16addr 16data
                hw_i2c_16write16(reg, val);
            }
            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;
            SendSensor_i2cClick?.Invoke("W:0x" + reg.ToString("X2")+" 0x"+val.ToString("X2"));
        }
        public void HwWrite(List<uint[]> dataList)
        {
            //停止AE
            debugEN = false;
            AE_Disable();
            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            //switch pin
            switch_pin_to_sensor();
            //发送 ID
            i2c_writereg(0x03, add);
            Action<uint, uint> action_hwWirte = null;
            //IAsyncResult asyncResult = null;           
            if (checkBox1)
            {// i2c_mode = 0; // 8addr 8data
                action_hwWirte = hw_i2c_write;
            }
            else if (checkBox2)
            {// i2c_mode = 1;  // 16addr 8data
                action_hwWirte = hw_i2c_write16;
            }
            else if (checkBox3)
            {// i2c_mode = 2;  // 16addr 16data
                action_hwWirte = hw_i2c_16write16;
            }

            if (null != action_hwWirte)
            {
                foreach (var item in dataList)
                {
                    //debugEN = false;
                    action_hwWirte.Invoke(item[0], item[1]);
                    //debugEN = true;
                    SendSensor_i2cClick?.Invoke("W:0x" + item[0].ToString("X2") + " 0x" + item[1].ToString("X2"));
                }
            }
            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;
        }

        private uint hw_i2c_read(uint addr)
        {
            uint val;
            I2C_RDY();
            i2c_writereg(0x05, addr);
            i2c_writereg(0x04, 0x33);
            Thread.Sleep(2);

            //I2C_WaitReady();
            i2c_writereg(0x04, 0xf9);
            Thread.Sleep(2);

            //I2C_WaitReady();
            val = i2c_readreg(0x07);
            return val;
        }

        private uint hw_i2c_read16(uint addr)
        {
            uint val;
            I2C_RDY();

            i2c_writereg(0x05, (addr >> 8) & 0xff);
            i2c_writereg(0x06, addr & 0xff);
            i2c_writereg(0x04, 0x37);

            //I2C_WaitReady();
            i2c_writereg(0x04, 0xf9);

            //I2C_WaitReady();

            val = i2c_readreg(0x07);
            return val;

        }
        private uint hw_i2c_16read16(uint addr)
        {
            uint val, val1, val2;

            i2c_writereg(0x05, (addr >> 8) & 0xff);
            i2c_writereg(0x06, addr & 0xff);
            i2c_writereg(0x04, 0x17);
            Thread.Sleep(10);

            //I2C_WaitReady();
            i2c_writereg(0x04, 0x59);
            Thread.Sleep(10);

            //I2C_WaitReady();
            val1 = i2c_readreg(0x07);

            i2c_writereg(0x04, 0xa8);
            val2 = i2c_readreg(0x07);
            Thread.Sleep(10);

            //I2C_WaitReady();
            val = (val1 << 8) + val2;
            return val;
        }

        public string HwRead() {
            uint val = 0xfffffff; ;// = Convert.ToUInt32(sensor_val.Text, 16);
            //停止AE
            debugEN = false;
            AE_Disable();

            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            // switch pin
            switch_pin_to_sensor();
            //发送 ID
            i2c_writereg(0x03, add);
            //导出的文本字符串
          
                if (checkBox1)
                {
                    // i2c_mode = 0; // 8addr 8data
                    val = hw_i2c_read(reg);
                }
                else if (checkBox2)
                {
                    // i2c_mode = 1;  // 16addr 8data
                    val = hw_i2c_read16(reg);
                }
                else if (checkBox3)
                {
                    // i2c_mode = 2;  // 16addr 16data
                    val = hw_i2c_16read16(reg);
                }
                SendSensor_i2cClick?.Invoke("R:0x" + reg.ToString("X2") + " 0x" + val.ToString("X2"));
            
            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;
          
            return Convert.ToString(val, 16).ToUpper();
        }


        public string ReadRegByLoop(uint endAdd)
        {
            uint val = 0xfffffff; ;// = Convert.ToUInt32(sensor_val.Text, 16);
            //停止AE
            debugEN = false;
            AE_Disable();

            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            // switch pin
            switch_pin_to_sensor();

            i2c_writereg(0x03, add);

            int myRegX = (int)reg;
            StringBuilder sbRegTxt = new StringBuilder();
            //   int tempLenth = (int)(myEndAdd - myRegX);

            for (int i = myRegX; i <= (int)endAdd; i++)
            {
                uint myReg = (uint)(i);


                if (checkBox1)
                {
                    // i2c_mode = 0; // 8addr 8data
                    val = hw_i2c_read(myReg);
                }
                else if (checkBox2)
                {
                    // i2c_mode = 1;  // 16addr 8data
                    val = hw_i2c_read16(myReg);
                }
                else if (checkBox3)
                {
                    // i2c_mode = 2;  // 16addr 16data
                    val = hw_i2c_16read16(myReg);
                }

                sbRegTxt.Append("R:0x");
                sbRegTxt.Append(myReg.ToString("X2"));
                sbRegTxt.Append(" 0x");
                sbRegTxt.Append(val.ToString("X2"));
                sbRegTxt.Append("\n");

                SendSensor_i2cClick?.Invoke("R:0x" + myReg.ToString("X2") + " 0x" + val.ToString("X2"));


            }

            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;
            return sbRegTxt.ToString();




        }

        public string ReadRegByLoop(uint endAdd,int step)
        {
            uint val = 0xfffffff; ;// = Convert.ToUInt32(sensor_val.Text, 16);
            //停止AE
            debugEN = false;
            AE_Disable();

            Thread.Sleep(30);
            //切成master
            I2C_Switch_Master();
            // switch pin
            switch_pin_to_sensor();

            i2c_writereg(0x03, add);

            int myRegX = (int)reg;
            StringBuilder sbRegTxt = new StringBuilder();
            //   int tempLenth = (int)(myEndAdd - myRegX);

            for (int i = myRegX; i <= (int)endAdd; i+=step)
            {
                uint myReg = (uint)(i);


                if (checkBox1)
                {
                    // i2c_mode = 0; // 8addr 8data
                    val = hw_i2c_read(myReg);
                }
                else if (checkBox2)
                {
                    // i2c_mode = 1;  // 16addr 8data
                    val = hw_i2c_read16(myReg);
                }
                else if (checkBox3)
                {
                    // i2c_mode = 2;  // 16addr 16data
                    val = hw_i2c_16read16(myReg);
                }

                sbRegTxt.Append("R:0x");
                sbRegTxt.Append(myReg.ToString("X2"));
                sbRegTxt.Append(" 0x");
                sbRegTxt.Append(val.ToString("X2"));
                sbRegTxt.Append("\n");

                SendSensor_i2cClick?.Invoke("R:0x" + myReg.ToString("X2") + " 0x" + val.ToString("X2"));


            }

            //切成slaver
            I2C_Switch_Slaver();
            //打开AE
            AE_Enable();
            debugEN = true;
            return sbRegTxt.ToString();




        }

    }
}
